package org.aeon.gamechatnest.service.impl;

import org.aeon.gamechatnest.common.Constant;
import org.aeon.gamechatnest.common.enumeration.DefaultRoleEnum;
import org.aeon.gamechatnest.common.response.ResultBuild;
import org.aeon.gamechatnest.dto.UserCacheDto;
import org.aeon.gamechatnest.mapper.UserServerMapper;
import org.aeon.gamechatnest.pojo.Role;
import org.aeon.gamechatnest.pojo.RoleAuthority;
import org.aeon.gamechatnest.pojo.RoleUser;
import org.aeon.gamechatnest.pojo.UserServer;
import org.aeon.gamechatnest.service.RoleService;
import org.aeon.gamechatnest.service.TextChannelService;
import org.aeon.gamechatnest.service.UserServerService;
import org.aeon.gamechatnest.util.ApplicationAssert;
import org.aeon.gamechatnest.util.RedisCache;
import org.aeon.gamechatnest.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author :Liys 2024年5月9日
 */
@Service
public class UserServerServiceImpl implements UserServerService {
    @Autowired
    private UserServerMapper userServerMapper;

    // 调取同层服务时应当懒加载
    @Lazy
    @Autowired
    private RoleService roleService;

    @Autowired
    private RedisCache redisCache;

    // 调取同层服务时应当懒加载
    @Lazy
    @Autowired
    private TextChannelService textChannelService;

    @Override
    @Transactional
    public boolean save(UserServer userServer) {
        // 获取当前用户id
        Long userId = SecurityUtil.getUserId();
        userServer.setUserId(userId);
        userServer.setCreateTime(new Date());
        ApplicationAssert.isSuccess(userServerMapper.add(userServer) > 0, "服务器创建失败");

        // 创建服务器时，创建默认服务器角色
        DefaultRoleEnum.stream().findFirst().ifPresent(defaultRole -> {
            Role role = createDefaultRole(userServer, defaultRole);
            // 为该用户添加在当前服务器权限
            RoleUser roleUser = new RoleUser(role.getRoleId(), userId, new Date());
            ApplicationAssert.isSuccess(roleService.addRoleToServerUser(roleUser), "添加角色关联失败");
        });

        DefaultRoleEnum.stream().skip(1).forEach(defaultRole -> createDefaultRole(userServer, defaultRole));
        ApplicationAssert.isSuccess(textChannelService.createDefaultChannel(userServer.getServerId()), "创建默认频道失败");
        return true;
    }

    public Role createDefaultRole(UserServer userServer, DefaultRoleEnum defaultRole) {
        Role role = new Role(null, userServer.getServerId(), defaultRole.toString(), new Date());
        // 创建服务器时，创建默认服务器角色
        ApplicationAssert.isSuccess(roleService.addDefaultRoleToServer(role), "服务器角色创建失败");
        // 为默认角色赋予权限
        defaultRole.getAuthorityIds().forEach(authorityId -> {
            RoleAuthority roleAuthority = new RoleAuthority(authorityId, role.getRoleId());
            ApplicationAssert.isSuccess(roleService.addAuthorityToRole(roleAuthority), "添加权限失败");
        });
        return role;
    }

    @Override
    @Transactional
    public boolean removeById(Long serverId) {
        if (isNotExist(serverId)) {
            ResultBuild.result().message("服务器不存在");
            return false;
        }
        // 删除服务器时，删除服务器角色
        roleService.removeServerRole(serverId);
        // 删除服务器时，删除频道
        textChannelService.removeByServerId(serverId);
        // TODO 删除服务器时，删除服务器成员
        return userServerMapper.deleteById(serverId) > 0;
    }

    @Override
    public boolean modifyById(UserServer userServer) {
        if (isNotExist(userServer.getServerId())) {
            ResultBuild.result().message("服务器不存在");
            return false;
        }
        return userServerMapper.updateById(userServer) > 0;
    }

    @Override
    public List<UserServer> findByName(String name) {
        return userServerMapper.getByName(name);
    }

    @Override
    public UserServer findById(Long id) {
        return userServerMapper.getById(id);
    }

    @Override
    public List<UserServer> findByUserId(Long userId) {
        return userServerMapper.getByUserId(userId);
    }

    @Override
    public boolean isExist(Long serverId) {
        return userServerMapper.isExist(serverId);
    }

    @Override
    public boolean isNotExist(Long serverId) {
        return !isExist(serverId);
    }

    @Override
    public boolean useServer(Long serverId) {
        if (isNotExist(serverId)) {
            ResultBuild.result().message("服务器不存在");
            return false;
        }
        String key = Constant.USER_TOKEN_CACHE_PREFIX + SecurityUtil.getUsername();
        UserCacheDto userCache = redisCache.getCacheObject(key);
        ApplicationAssert.nonNull(userCache);
        userCache.setServerId(serverId);
        Set<String> authority = roleService
                .findAuthorityByUserIdAndServerId(userCache.getUser().getUserId(), userCache.getServerId());
        userCache.setAuthority(authority);
        redisCache.setCacheObject(key, userCache);
        return true;
    }
}
